<?php
namespace app\common\service;

use app\common\util\Random;
use app\common\wxpay\lib\WxPayApi;
use app\common\wxpay\lib\WxPayException;
use app\common\wxpay\lib\WxPayJsApiPay;
use app\common\wxpay\lib\WxPayUnifiedOrder;
use app\common\wxpay\WxPayConfig;
use EasyWeChat\Factory;

class WxPayService{

    /**
     * 小程序支付
     * @param String $openid
     * @param int $fee 单位分
     * @param string $tradeNo 订单编号
     * @param string $body
     * @return array
     */
    public function wxAppPay($openid,$fee,$tradeNo,$body){
        $notifyUrl = env('wxapp.wxpay_notify_url');
        $wxPayUnifiedOrder = new WxPayUnifiedOrder();
        $wxPayUnifiedOrder->SetOut_trade_no($tradeNo);
        $wxPayUnifiedOrder->SetTrade_type('JSAPI');
        $wxPayUnifiedOrder->SetTotal_fee($fee);
        $wxPayUnifiedOrder->SetBody($body);
        $wxPayUnifiedOrder->SetOpenid($openid);
        $wxPayUnifiedOrder->SetSignType("MD5");
        $wxPayUnifiedOrder->SetNotify_url($notifyUrl);
        $wxConfig = new WxPayConfig();
        $wxOrder = WxPayApi::unifiedOrder($wxConfig,$wxPayUnifiedOrder);
        

        $data = [];
        $data['appId'] =$wxOrder['appid'];
        $data['timeStamp'] = time();
        $data['nonceStr'] = Random::rand(30);
        $data['package'] = "prepay_id=".$wxOrder['prepay_id'];
        $data['signType'] = 'MD5';

        ksort($data);

        //用http_build_query会url编码 因此签名会出错
        $stringSignTemp = $this->ToUrlParams($data);
        $stringSignTemp .= "&key=".$wxConfig->GetKey();
        $sign = strtoupper(md5($stringSignTemp));

        $result = [];
        $result['timeStamp'] = $data['timeStamp'];
        $result['nonceStr'] = $data['nonceStr'];
        $result['package'] = $data['package'];
        $result['signType'] = 'MD5';
        $result['paySign'] = $sign;

        return $result;
    }

    public function wxMpPay($openid,$fee,$tradeNo,$body){
        $notifyUrl = env('wxapp.wxpay_notify_url');
        $wxPayUnifiedOrder = new WxPayUnifiedOrder();
        $wxPayUnifiedOrder->SetOut_trade_no($tradeNo);
        $wxPayUnifiedOrder->SetTrade_type('JSAPI');
        $wxPayUnifiedOrder->SetTotal_fee($fee);
        $wxPayUnifiedOrder->SetBody($body);
        $wxPayUnifiedOrder->SetOpenid($openid);
        $wxPayUnifiedOrder->SetSignType("MD5");
        $wxPayUnifiedOrder->SetNotify_url($notifyUrl);
        $wxConfig = new WxPayConfig();
        $wxOrder = WxPayApi::unifiedOrder($wxConfig,$wxPayUnifiedOrder);


        $data = [];
        $data['appId'] =$wxOrder['appid'];
        $data['timeStamp'] = time().'';
        $data['nonceStr'] = Random::rand(30);
        $data['package'] = "prepay_id=".$wxOrder['prepay_id'];
        $data['signType'] = 'MD5';

        ksort($data);

        //用http_build_query会url编码 因此签名会出错
        $stringSignTemp = $this->ToUrlParams($data);
        $stringSignTemp .= "&key=".$wxConfig->GetKey();
        $sign = strtoupper(md5($stringSignTemp));

        $result = [];
        $result['appId'] = $data['appId'];
        $result['timeStamp'] = $data['timeStamp'];
        $result['nonceStr'] = $data['nonceStr'];
        $result['package'] = $data['package'];
        $result['signType'] = 'MD5';
        $result['paySign'] = $sign;

        return $result;
    }

    public function GetJsApiParameters($UnifiedOrderResult)
    {
        if(!array_key_exists("appid", $UnifiedOrderResult)
            || !array_key_exists("prepay_id", $UnifiedOrderResult)
            || $UnifiedOrderResult['prepay_id'] == "")
        {
            throw new WxPayException("参数错误");
        }

        $jsapi = new WxPayJsApiPay();
        $jsapi->SetSignType("MD5");
        $jsapi->SetAppid($UnifiedOrderResult["appid"]);
        $timeStamp = time();
        $jsapi->SetTimeStamp("$timeStamp");
        $jsapi->SetNonceStr(WxPayApi::getNonceStr());
        $jsapi->SetPackage("prepay_id=" . $UnifiedOrderResult['prepay_id']);

        $config = new WxPayConfig();
        $jsapi->SetPaySign($jsapi->MakeSign($config));
        $parameters = json_encode($jsapi->GetValues());
        return $parameters;
    }

    /**
     * 格式化参数格式化成url参数
     * @param $data
     * @return string
     */
    public function ToUrlParams($data)
    {
        $buff = "";
        foreach ($data as $k => $v)
        {
            if($k != "sign" && $v != "" && !is_array($v)){
                $buff .= $k . "=" . $v . "&";
            }
        }

        $buff = trim($buff, "&");
        return $buff;
    }
}